<template>
    <!-- 首行输入框 -->
    <input v-if="lineConfig.firstLine.chars > 0" ref="firstLineInput" v-model="lines[0].value" class="inputStyle"
           :style="getInputStyle(0)" @input="handleInput(0, $event)" @keydown.delete="handleDelete(0, $event)"
           @focus="handleFocus(0)" @compositionstart="handleCompositionStart"
           @compositionend="(e) => handleCompositionEnd(e, 0)">

    <!-- 中间行输入框 -->
    <input v-for="(line, index) in middleLines" :key="'middle-' + index"
           :ref="el => { if (el) middleLineInputs[index] = el }" v-model="lines[line.realIndex].value" class="inputStyle"
           :style="getInputStyle(line.realIndex)" @input="handleInput(line.realIndex, $event)"
           @keydown.delete="handleDelete(line.realIndex, $event)" @focus="handleFocus(line.realIndex)"
           @compositionstart="handleCompositionStart" @compositionend="(e) => handleCompositionEnd(e, line.realIndex)">

    <!-- 末行输入框 -->
    <input v-if="lineConfig.lastLine.chars > 0" ref="lastLineInput" v-model="lines[lastLineIndex].value"
           class="inputStyle" :style="getInputStyle(lastLineIndex)" @input="handleInput(lastLineIndex, $event)"
           @keydown.delete="handleDelete(lastLineIndex, $event)" @focus="handleFocus(lastLineIndex)"
           @compositionstart="handleCompositionStart" @compositionend="(e) => handleCompositionEnd(e, lastLineIndex)">
</template>

<script>
    import { ref, computed, watch, nextTick } from 'vue';
    import { debounce } from 'lodash-es';

    export default {
        props: {
            value: {
                type: String,
                default: ''
            },
            lineConfig: {
                type: Object,
                default: () => ({
                    firstLine: { chars: 0 },
                    middleLines: { count: 0, chars: 32 * 2 },
                    lastLine: { chars: 0 }
                }),
                required: true
            }
        },
        setup(props, { emit }) {
            // 所有行的数据
            const lines = ref([]);
            // 当前聚焦的行索引
            const currentLine = ref(0);
            // 输入框引用
            const firstLineInput = ref(null);
            const middleLineInputs = ref([]);
            const lastLineInput = ref(null);
            // 记录上一次的值，用于比较
            const lastValue = ref('');
            // 拼音输入状态
            const isComposing = ref(false);
            // 检测是否为Firefox浏览器
            const isFirefox = ref(navigator.userAgent.includes('Firefox'));

            // 计算属性
            const middleLines = computed(() => {
                const start = props.lineConfig.firstLine.chars > 0 ? 1 : 0;
                const end = start + props.lineConfig.middleLines.count;
                return Array.from({ length: props.lineConfig.middleLines.count }, (_, i) => ({
                    realIndex: start + i
                }));
            });

            const lastLineIndex = computed(() => {
                let index = 0;
                if (props.lineConfig.firstLine.chars > 0) index++;
                index += props.lineConfig.middleLines.count;
                return index;
            });

            // 初始化行数据
            const initLines = () => {
                const newLines = [];

                if (props.lineConfig.firstLine.chars > 0) {
                    newLines.push({ maxChars: props.lineConfig.firstLine.chars, value: '' });
                }

                for (let i = 0; i < props.lineConfig.middleLines.count; i++) {
                    newLines.push({ maxChars: props.lineConfig.middleLines.chars, value: '' });
                }

                if (props.lineConfig.lastLine.chars > 0) {
                    newLines.push({ maxChars: props.lineConfig.lastLine.chars, value: '' });
                }

                lines.value = newLines;
            };

            // 获取输入框样式
            const getInputStyle = (lineIndex) => ({
                width: `${lines.value[lineIndex].maxChars * 2.5}mm`,
                fontFamily: '仿宋',
                fontSize: '5mm',
            });

            // 计算字符长度（中文2，英文1）
            const getCharLength = (str) => {
                let length = 0;
                for (let i = 0; i < str.length; i++) {
                    const charCode = str.charCodeAt(i);
                    length += (charCode > 127 || charCode === 94) ? 2 : 1;
                }
                return length;
            };

            // 拼音输入开始（防止输入拼音导致输入框聚焦到下一行）
            const handleCompositionStart = () => {
                isComposing.value = true;
            };

            // 拼音输入结束
            const handleCompositionEnd = async (event, lineIndex) => {
                isComposing.value = false;
                await handleInputActual(lineIndex, {
                    target: event.target,
                    data: null
                });
            };

            // 处理聚焦逻辑
            const handleFocus = async (lineIndex) => {
                currentLine.value = lineIndex; // 更新当前行索引
                const currentLineData = lines.value[lineIndex];

                // 若当前行是空的，则跳转到上一行内容末尾
                if (currentLineData.value === '' && lineIndex > 0) {
                    // 查找上面行中最后一个有内容的行
                    let targetLineIndex = -1;
                    for (let i = lineIndex - 1; i >= 0; i--) {
                        if (lines.value[i].value !== '') {
                            targetLineIndex = i;
                            break;
                        }
                    }

                    // 若找到有内容的上一行，聚焦到其末尾
                    if (targetLineIndex !== -1) {
                        await nextTick(); // 等待DOM更新
                        focusLine(targetLineIndex);
                        setCursorPosition(targetLineIndex, lines.value[targetLineIndex].value.length);
                        return; // 终止当前聚焦逻辑
                    } else {
                        // 所有行都为空，聚焦到第一行
                        targetLineIndex = 0;
                        await nextTick();
                        focusLine(targetLineIndex);
                        setCursorPosition(targetLineIndex, 0);
                        return;
                    }
                }
            };

            // 实际输入处理逻辑
            const handleInputActual = async (lineIndex, event) => {
                const input = event.target;
                // 当前输入框的值
                const currentValue = input.value;
                const cursorPos = input.selectionStart;
                const originalValue = lines.value[lineIndex].value; // 输入前的原始值

                if (lastValue.value === currentValue) return;
                lastValue.value = currentValue;

                // 基础数据计算
                const currentLine = lines.value[lineIndex];
                // 长度（中文2，英文1）
                const originalLength = getCharLength(originalValue);
                const currentLength = getCharLength(currentValue);
                // 是否溢出
                const isOverflow = currentLength > currentLine.maxChars; // 改为严格大于

                // 重新分配内容
                await recalculateLines();

                // 增加的字符数
                const addLength = updateCombinedValue();

                // 等待DOM更新
                await nextTick();

                // 溢出光标处理
                if (isOverflow && lineIndex < lines.value.length - 1) {
                    // 获取更新后的当前行数据
                    const currentLineAfter = lines.value[lineIndex];
                    const currentLineAfterLength = currentLineAfter.value.length;

                    // 计算最大光标位置
                    const maxCursorPos = currentLineAfterLength;

                    if (cursorPos + addLength <= maxCursorPos) {
                        // 未溢出，保持当前行光标
                        setCursorPosition(lineIndex, Math.min(cursorPos, currentLineAfterLength));
                    } else {
                        // 溢出，计算新行和新光标位置
                        let newLineIndex = lineIndex + 1;
                        let newCursorPos = cursorPos + addLength - maxCursorPos;

                        // 处理多级溢出
                        while (newLineIndex < lines.value.length) {
                            const nextLine = lines.value[newLineIndex];
                            const nextLineMaxLength = nextLine.value.length;
                            const nextLineMaxChars = nextLine.maxChars;

                            // 检查下一行是否也会溢出
                            if (newCursorPos > nextLineMaxLength && getCharLength(nextLine.value) >= nextLineMaxChars) {
                                newCursorPos -= nextLineMaxLength;
                                newLineIndex++;
                            } else {
                                break;
                            }
                        }

                        // 边界保护
                        if (newLineIndex >= lines.value.length) {
                            newLineIndex = lines.value.length - 1;
                            newCursorPos = lines.value[newLineIndex].value.length;
                        }

                        // 针对Firefox使用setTimeout确保光标设置生效
                        if (isFirefox.value) {
                            setTimeout(() => {
                                setCursorPosition(newLineIndex, newCursorPos);
                            }, 0);
                        } else {
                            setCursorPosition(newLineIndex, newCursorPos);
                        }
                    }
                } else {
                    // 未溢出，保持光标在当前行
                    setCursorPosition(lineIndex, Math.min(cursorPos, currentValue.length));
                }
            };

            // 防抖处理函数 - 仅对非Firefox浏览器使用防抖
            const debouncedHandleInput = debounce(handleInputActual, 100);

            // 处理输入（外层包装）
            const handleInput = (lineIndex, event) => {
                if (isComposing.value) return;

                // Firefox不使用防抖，其他浏览器使用防抖
                if (isFirefox.value) {
                    handleInputActual(lineIndex, event);
                } else {
                    debouncedHandleInput(lineIndex, event);
                }
            };

            // 删除操作
            const handleDelete = async (lineIndex, event) => {
                // 阻止默认删除行为
                event.preventDefault();

                const input = event.target;
                const cursorPos = input.selectionStart;
                const currentValue = lines.value[lineIndex].value;

                // 如果在行首按删除键，且上一行存在
                if (cursorPos === 0 && lineIndex > 0) {
                    // 合并当前行到上一行
                    const prevLine = lines.value[lineIndex - 1];
                    const currentLine = lines.value[lineIndex];

                    // 检查上一行是否有空间
                    const spaceAvailable = prevLine.maxChars - getCharLength(prevLine.value);
                    const currentLineHasContent = currentValue.length > 0;

                    if (spaceAvailable > 0 && currentLineHasContent) {
                        // 移动尽可能多的字符到上一行
                        const { extracted, remaining } = extractChars(currentLine.value, spaceAvailable);
                        prevLine.value += extracted;
                        currentLine.value = remaining;

                        // 重新计算所有行的内容，确保内容连续
                        await recalculateLines();

                        // 保持光标在当前行（除非当前行已空）
                        if (remaining.length > 0) {
                            await nextTick();
                            setCursorPosition(lineIndex, 0); // 留在当前行开头
                        } else {
                            // 当前行已空，才移动到上一行末尾
                            await nextTick();
                            setCursorPosition(lineIndex - 1, prevLine.value.length);
                        }
                    } else {
                        // 上一行无空间或当前行无内容，才移动到上一行末尾
                        focusLine(lineIndex - 1);
                        setCursorPosition(lineIndex - 1, prevLine.value.length);
                    }
                }
                // 普通删除操作
                else if (cursorPos > 0) {
                    // 手动执行删除操作
                    const newValue = currentValue.substring(0, cursorPos - 1) +
                        currentValue.substring(cursorPos);

                    // 直接更新当前行的值
                    lines.value[lineIndex].value = newValue;

                    // 从下一行开始，级联向前补充内容
                    await cascadeFillForward(lineIndex);

                    // 设置光标位置（保持在当前行）
                    await nextTick();
                    setCursorPosition(lineIndex, cursorPos - 1);
                }

                updateCombinedValue();
            };

            // 从指定行开始，级联向前补充内容
            const cascadeFillForward = async (startLineIndex) => {
                for (let i = startLineIndex; i < lines.value.length - 1; i++) {
                    const currentLine = lines.value[i];
                    const nextLine = lines.value[i + 1];

                    // 计算当前行剩余空间
                    const spaceAvailable = currentLine.maxChars - getCharLength(currentLine.value);
                    if (spaceAvailable <= 0) break;

                    // 从下一行提取字符填补当前行
                    const { extracted, remaining } = extractChars(nextLine.value, spaceAvailable);
                    currentLine.value += extracted;
                    nextLine.value = remaining;

                    // 如果下一行被完全移动，继续处理更下面的行
                    if (remaining.length === 0) {
                        await nextTick();
                    } else {
                        break;
                    }
                }

                // 检查是否需要重新计算所有行（当有跨多行的内容移动时）
                const combined = lines.value.map(line => line.value).join('');
                if (getCharLength(combined) !== lastValue.value.length) {
                    await recalculateLines();
                }
            };

            // 重新计算所有行的内容
            const recalculateLines = async () => {
                // 合并所有行内容
                let combined = lines.value.map(line => line.value).join('');

                // 清空所有行
                lines.value.forEach(line => line.value = '');

                // 重新分配内容到各行
                let remaining = combined;
                for (let i = 0; i < lines.value.length; i++) {
                    const { extracted, remaining: newRemaining } = extractChars(remaining, lines.value[i].maxChars);
                    lines.value[i].value = extracted;
                    remaining = newRemaining;

                    if (remaining.length === 0) break;
                }
            };

            // 聚焦到指定行
            const focusLine = (lineIndex) => {
                currentLine.value = lineIndex;
                let input = null;

                if (lineIndex === 0 && firstLineInput.value) {
                    input = firstLineInput.value;
                } else if (lineIndex === lastLineIndex.value && lastLineInput.value) {
                    input = lastLineInput.value;
                } else if (lineIndex > 0 && lineIndex < lastLineIndex.value) {
                    input = middleLineInputs.value[lineIndex - (props.lineConfig.firstLine.chars > 0 ? 1 : 0)];
                }

                if (input) {
                    input.focus();
                }
            };

            // 设置光标位置
            const setCursorPosition = (lineIndex, position) => {
                let input = null;

                if (lineIndex === 0 && firstLineInput.value) {
                    input = firstLineInput.value;
                } else if (lineIndex === lastLineIndex.value && lastLineInput.value) {
                    input = lastLineInput.value;
                } else if (lineIndex > 0 && lineIndex < lastLineIndex.value) {
                    input = middleLineInputs.value[lineIndex - (props.lineConfig.firstLine.chars > 0 ? 1 : 0)];
                }

                if (input) {
                    // Firefox需要先聚焦再设置光标
                    if (isFirefox.value) {
                        input.focus();
                        // 强制同步设置光标位置
                        input.selectionStart = position;
                        input.selectionEnd = position;
                        // 显式触发focus事件确保Firefox更新
                        input.dispatchEvent(new Event('focus'));
                    } else {
                        focusLine(lineIndex);
                        input.selectionStart = position;
                        input.selectionEnd = position;
                    }
                }
            };

            // 从字符串中提取指定长度的字符
            const extractChars = (str, maxChars) => {
                let takeLength = 0;
                let extracted = '';
                let i = 0;

                for (; i < str.length; i++) {
                    const charCode = str.charCodeAt(i);
                    const charSize = (charCode > 127 || charCode === 94) ? 2 : 1;

                    if (takeLength + charSize > maxChars) break;

                    takeLength += charSize;
                    extracted += str[i];
                }

                return {
                    extracted,
                    remaining: str.slice(i)
                };
            };

            // 更新合并后的值
            const updateCombinedValue = () => {
                const combined = lines.value.map(line => line.value).join('');
                // 判断是否新增
                let addLength = 0;
                // 之前的长度
                const updateBeforeLenght = props.value.length
                // 更新后的长度
                const updateAfterLenght = combined.length
                if (updateBeforeLenght < updateAfterLenght) {
                    // 新增的字符数
                    addLength = updateAfterLenght - updateBeforeLenght
                } else {
                    // 没有新增内容
                    addLength = 0;
                }

                lastValue.value = combined;
                // 更新父组件的value
                emit('update:value', combined);
                return addLength
            };

            // 拆分值到各行
            const splitValueToLines = (value) => {
                let remaining = value || '';

                for (let i = 0; i < lines.value.length; i++) {
                    const { extracted, remaining: newRemaining } = extractChars(remaining, lines.value[i].maxChars);
                    lines.value[i].value = extracted;
                    remaining = newRemaining;
                }
                lastValue.value = value;
            };

            // 监听props.value变化
            watch(() => props.value, (newVal) => {
                if (newVal !== lines.value.map(line => line.value).join('')) {
                    splitValueToLines(newVal);
                }
            });

            // 监听行配置变化
            watch(() => props.lineConfig, () => {
                initLines();
                splitValueToLines(props.value);
            }, { deep: true });

            // 初始化
            initLines();
            splitValueToLines(props.value);

            return {
                lines,
                currentLine,
                firstLineInput,
                middleLineInputs,
                lastLineInput,
                middleLines,
                lastLineIndex,
                isComposing,
                getInputStyle,
                handleInput,
                handleDelete,
                handleCompositionStart,
                handleCompositionEnd,
                handleFocus,
            };
        }
    };
</script>

<style scoped></style>
